#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    setWindowTitle("Firmwareupdate");       //窗口标题

    QWidget_Main = new QWidget;     //主窗体
    VQBoxLayout_Main = new QVBoxLayout; //串口布局 垂直布局

    setCentralWidget(QWidget_Main);     //设置中央的主控件,不设置主控件，无法显示页面

    vQGroupBox_Serial = new QGroupBox;      //串口容器

    vQWidget_FwUpdate_Main = new QWidget();     //更新相关窗口
    vQWidget_Serial_Text = new QWidget;         //文本显示窗口




    QWidget_Main->setLayout(VQBoxLayout_Main);  //将串口垂直布局添加到主窗口

    VQBoxLayout_Main->addWidget(vQGroupBox_Serial);     //串口参数配置布局
    VQBoxLayout_Main->addWidget(vQWidget_FwUpdate_Main);//IAP升级配置布局
    VQBoxLayout_Main->addWidget(vQWidget_Serial_Text);  //文本显示布局

    Serial_init();

    FirmWare_Update();



    //文本框显示
    vqtextEdit_serialText = new QTextEdit;
    vqtextEdit_serialText->setReadOnly(true);

    vqboxLayout_serialText = new QVBoxLayout;       //容器
    vQWidget_Serial_Text->setLayout(vqboxLayout_serialText);

    vqboxLayout_serialText->addWidget(vqtextEdit_serialText);


}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::Serial_init()
{
    QFont ft;
    ft.setPointSize(12);

    serial = new QSerialPort;
    ComBox_Port = new QComboBox;
    ComBox_Baud = new QComboBox;
    ComBox_DateBit = new QComboBox;
    ComBox_StopBit = new QComboBox;
    ComBox_CheckBit = new QComboBox;
    PushButton_Open = new QPushButton;

    Label_StateName = new QLabel("status:");

    Label_StateDate = new QLabel("serial port is disconnected");


    vQGroupBox_Serial->setTitle("serial port setup");       //设置串口容器标题
    //    vQGroupBox_Serial->setFlat(true);
    //    vQGroupBox_Serial->setChecked(true);

    QHBoxLayout_Serial = new QHBoxLayout(vQGroupBox_Serial);    //串口水平布局，并且将串口容器添加到布局中

    QHBoxLayout_Serial->addWidget(ComBox_Port);
    QHBoxLayout_Serial->addSpacing(10);

    QHBoxLayout_Serial->addWidget(ComBox_Baud);
    QHBoxLayout_Serial->addSpacing(10);
    QHBoxLayout_Serial->addWidget(ComBox_DateBit);
    QHBoxLayout_Serial->addSpacing(10);
    QHBoxLayout_Serial->addWidget(ComBox_StopBit);
    QHBoxLayout_Serial->addSpacing(10);
    QHBoxLayout_Serial->addWidget(ComBox_CheckBit);
    QHBoxLayout_Serial->addSpacing(10);
    QHBoxLayout_Serial->addWidget(PushButton_Open);
    QHBoxLayout_Serial->addSpacing(10);
    QHBoxLayout_Serial->addWidget(Label_StateName);
    QHBoxLayout_Serial->addSpacing(2);
    QHBoxLayout_Serial->addWidget(Label_StateDate);
    QHBoxLayout_Serial->addSpacing(10);

    //获取有效的串口信息
    foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts()){

        serial->setPort(info);
        if(serial->open(QIODevice::ReadWrite))
        {
            //将串口编号添加到combox
            ComBox_Port->addItem(info.portName());
            serial->close();        //关闭串口，等待人为打开
        }

    }

    //填充波特率
    QStringList Baud;
    Baud << "2400" << "4800" << "9600" << "38400" << "115200";
    ComBox_Baud->addItems(Baud);

    //填充数据位
    QStringList DataBit;
    DataBit << "5" << "6" << "7" << "8";
    ComBox_DateBit->addItems(DataBit);

    //填充停止位
    QStringList StopBit;
    StopBit << "1" << "1.5" << "2";
    ComBox_StopBit->addItems(StopBit);

    //填充校验位
    QStringList CheckBit;
    CheckBit << "None" << "Odd" << "Even";
    ComBox_CheckBit->addItems(CheckBit);

    //初始化默认参数
    ComBox_Baud->setCurrentIndex(4);        //默认115200
    ComBox_DateBit->setCurrentIndex(3);     //默认8位数据位
    ComBox_StopBit->setCurrentIndex(0);     //默认1位停止位
    ComBox_CheckBit->setCurrentIndex(0);    //默认无校验

    PushButton_Open->setText("connect");
    PushButton_Open->setFont(ft);
    PushButton_Open->setFixedHeight(20);
    PushButton_Open->setFixedWidth(100);
    PushButton_Open->setStyleSheet("background:rgb(127,188,233)");

    // 创建信号和槽
    connect(PushButton_Open,SIGNAL(clicked()),this,SLOT(SlotPushButton_Open()));

}

void MainWindow::revice_data()
{
    QString framedata;
    QByteArray readData = serial->readAll();        //读取所有串口所有数据
    qDebug() << readData;
    if(readData.isEmpty() != true)
    {
        copy_to_buff((uint8_t*)readData.data(),readData.size());
        Process();

        /* 将接收到的数据显示在文本框 */
        framedata = QString(readData);
        vqtextEdit_serialText->insertPlainText(framedata);
        vqtextEdit_serialText->moveCursor(QTextCursor::End);        /* 移动到文本最后 */
        qDebug() << framedata;
    }






}

void MainWindow::FirmWare_Update()
{
    QFont ft;

    ft.setPointSize(16);
    //定义主布局
    // 创建垂直布局管理器
    //    QVBoxLayout* layout = new QVBoxLayout();
    //    // 添加控件
    //    layout->addWidget(new QPushButton("按钮1"));
    //    layout->addWidget(new QPushButton("按钮2"));
    //    // 设置布局到窗口
    //    QWidget* widget = new QWidget();
    //    widget->setLayout(layout);

    qvboxLayout_FwUpdate_Main = new QVBoxLayout;  //垂直布局
    qvboxLayout_FwUpdate = new QVBoxLayout;

    qgroupBox_FwUpdate = new QGroupBox;     //容器

    vqLabel_FwUpdate_Path = new QLabel;

    vqLineEdit_FwUpdate_Path = new QLineEdit;

    vqPushButton_FwUpdate_Open = new QPushButton;

    vqPushButton_FwUpdate_Start = new QPushButton;

    vqLabel_FwUpdate_Prog = new QLabel;

    vqProgressBar_FwUpdate_Prog = new QProgressBar;

    vqLable_FwUpdate_StateName = new QLabel;

    vqLabel_FwUpdate_State_Data = new QLabel;




    vQWidget_FwUpdate_Main->setLayout(qvboxLayout_FwUpdate_Main);//将更新相关的布局添加到更新窗口

    qvboxLayout_FwUpdate_Main->addWidget(qgroupBox_FwUpdate);
    qvboxLayout_FwUpdate_Main->addStretch(1);

    qgroupBox_FwUpdate->setTitle("固件更新");
    qgroupBox_FwUpdate->setLayout(qvboxLayout_FwUpdate);

    vqLineEdit_FwUpdate_Path->setReadOnly(true);

    vqLabel_FwUpdate_Path->setText(tr("固件路径:"));
    vqLabel_FwUpdate_Path->setFont(ft);


    vqPushButton_FwUpdate_Open->setText(tr("打开固件"));
    vqPushButton_FwUpdate_Open->setFont(ft);
    vqPushButton_FwUpdate_Open->setFixedHeight(30);
    vqPushButton_FwUpdate_Open->setFixedWidth(150);

    qwidget_FwUpdate_1 = new QWidget;
    qhboxLayout_Fw_Update1 = new QHBoxLayout;

    qwidget_FwUpdate_2 = new QWidget;
    qhboxLayout_Fw_Update2 = new QHBoxLayout;

    qwidget_FwUpdate_3 = new QWidget;
    qhboxLayout_Fw_Update3 = new QHBoxLayout;
    
    qwidget_FwUpdate_4 = new QWidget;
    qhboxLayout_Fw_Update4 = new QHBoxLayout;



    qwidget_FwUpdate_1->setLayout(qhboxLayout_Fw_Update1);
    qhboxLayout_Fw_Update1->addWidget(vqLabel_FwUpdate_Path);
    qhboxLayout_Fw_Update1->addWidget(vqLineEdit_FwUpdate_Path);
    qhboxLayout_Fw_Update1->addWidget(vqPushButton_FwUpdate_Open);

    vqLabel_FwUpdate_Type = new QLabel;
    vqLabel_FwUpdate_Type->setText(tr("更新方式:"));
    vqLabel_FwUpdate_Type->setFont(ft);


    vqLabel_FwUpdate_Dev = new QLabel;
    vqLabel_FwUpdate_Dev->setText(tr("更新机器:"));
    vqLabel_FwUpdate_Dev->setFont(ft);

    vqComboBox_FwUpdate_Dev = new QComboBox;
    QStringList heatcool;

    heatcool << "UI"<<"MCU";
    vqComboBox_FwUpdate_Dev->addItems(heatcool);
    vqComboBox_FwUpdate_Dev->setFixedHeight(30);
    vqComboBox_FwUpdate_Dev->setFixedWidth(130);
    vqComboBox_FwUpdate_Dev->setCurrentIndex(1);        /**默认是MCU */

    vqComboBox_FwUpdate_Type = new QComboBox;
    QStringList heatcool1;

    heatcool1 << "ISP"<<"IAP";
    vqComboBox_FwUpdate_Type->addItems(heatcool1);
    vqComboBox_FwUpdate_Type->setFixedHeight(30);
    vqComboBox_FwUpdate_Type->setFixedWidth(60);
    vqComboBox_FwUpdate_Type->setCurrentIndex(0);        /**默认是ISP */


    vqPushButton_FwUpdate_Start->setText(tr("更新固件"));
    vqPushButton_FwUpdate_Start->setFont(ft);
    vqPushButton_FwUpdate_Start->setFixedHeight(30);    /* 按键高度 */
    vqPushButton_FwUpdate_Start->setFixedWidth(150);    /* 按键宽度 */

    qwidget_FwUpdate_2->setLayout(qhboxLayout_Fw_Update2);

    qhboxLayout_Fw_Update2->addWidget(vqLabel_FwUpdate_Dev);
    qhboxLayout_Fw_Update2->addWidget(vqComboBox_FwUpdate_Dev);
    qhboxLayout_Fw_Update2->addSpacing(50);
    qhboxLayout_Fw_Update2->addWidget(vqLabel_FwUpdate_Type);
    qhboxLayout_Fw_Update2->addWidget(vqComboBox_FwUpdate_Type);
    qhboxLayout_Fw_Update2->addStretch(0);
    qhboxLayout_Fw_Update2->addWidget(vqPushButton_FwUpdate_Start);


    vqLabel_FwUpdate_Prog->setText(tr("更新进度:"));
    vqLabel_FwUpdate_Prog->setFont(ft);

    vqProgressBar_FwUpdate_Prog->setRange(0,100);
    vqProgressBar_FwUpdate_Prog->setValue(0);

    qwidget_FwUpdate_3->setLayout(qhboxLayout_Fw_Update3);
    qhboxLayout_Fw_Update3->addWidget(vqLabel_FwUpdate_Prog);
    qhboxLayout_Fw_Update3->addWidget(vqProgressBar_FwUpdate_Prog);

    vqLable_FwUpdate_StateName->setText(tr("更新状态:"));
    vqLable_FwUpdate_StateName->setFont(ft);
    vqLable_FwUpdate_StateName->setAlignment(Qt::AlignRight);  //右对齐

    vqLabel_FwUpdate_State_Data->setText(tr("准备打开固件"));
    vqLabel_FwUpdate_State_Data->setFont(ft);

    qwidget_FwUpdate_4->setLayout(qhboxLayout_Fw_Update4);
    qhboxLayout_Fw_Update4->addWidget(vqLable_FwUpdate_StateName);
    qhboxLayout_Fw_Update4->addWidget(vqLabel_FwUpdate_State_Data);



    qvboxLayout_FwUpdate->addWidget(qwidget_FwUpdate_1);//显示了加载地址对话框和按键
    qvboxLayout_FwUpdate->addWidget(qwidget_FwUpdate_2);//显示了更新标签和更新类型的comboBox、更新方式
    qvboxLayout_FwUpdate->addWidget(qwidget_FwUpdate_3);//显示了更新的进度条和label
    qvboxLayout_FwUpdate->addWidget(qwidget_FwUpdate_4);//显示了更新的状态

    /* 定时器 */
    vQtimer_FwUpdate = new QTimer;
    vQtimer_IspStart = new QTimer;
    vQtimer_UpdateMcu = new QTimer;


    /*信号和槽 */
    connect(vQtimer_FwUpdate,SIGNAL(timeout()),this,SLOT(SoltFwUpdateTimerDone()));

    connect(vQtimer_IspStart,SIGNAL(timeout()),this,SLOT(SoltFwUpdateTimerIspStart()));

    connect(vQtimer_UpdateMcu,SIGNAL(timeout()),this,SLOT(SloatTimerUpdateMcu()));

    connect(vqPushButton_FwUpdate_Open,SIGNAL(clicked()),this,SLOT(SlotOpenFile()));

    connect(vqPushButton_FwUpdate_Start,SIGNAL(clicked()),this,SLOT(SlotFirmwareStat()));

    connect(vqComboBox_FwUpdate_Dev,SIGNAL(currentIndexChanged(int)),this,SLOT(SlotComboBox_FwUpdate_dev()));

    /* 文件操作 */
    QString dir;

    QFile file("path.txt");
    if(file.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        QTextStream in(&file);
        dir = in.readAll();
        qDebug() << dir;
    }
    vqLineEdit_FwUpdate_Path->setText(dir);



}

void MainWindow::copy_to_buff(uint8_t *buff, uint32_t len)
{
    uint32_t templen;
    uint32_t head,count,mlen;

    if(len == 0)
    {
        return;
    }

    if(len > 2*1024)
    {
        templen = 2*1024;
    }
    else
    {
        templen = len;
    }

    if((vCount + templen) < 2*1024)
    {
        if((vHead+vCount+templen) > 2*1024)
        {
            memmove(vBuff,vBuff+vHead,vCount);
            vHead = 0;
        }

        memcpy(vBuff+vCount+vHead,buff,templen);
        vCount = vCount + templen;


    }
    else
    {
        memcpy(vBuff,buff,templen);
        vHead = 0;
        vCount = templen;
    }

}

void MainWindow::Process()
{
    uint32_t head,count,reslen;
    head = vHead;
    count = vCount;
    while(count > 6)
    {
        if(vUpdateFlag == 0)
        {
            reslen = count;

        }
        else if(vUpdateFlag == 1)
        {
            reslen = Analyse_UI(vBuff+head,count);
        }
        else
        {
            reslen = Analyse_MCU(vBuff+head,count);
        }

        if(reslen > 0)
        {
            head += reslen;
            count -=reslen;
        }
        else
        {
            break;
        }
    }


    if(count == 0)
    {
        vHead = 0;
        vCount =0;
        memset(vBuff,0,2*1024);

    }
    else
    {
        vHead = head;
        vCount = count;
    }
}

uint32_t MainWindow::Analyse_UI(uint8_t *buff, uint32_t len)
{
    uint8_t i;
    uint16_t checksum;
    uint8_t framelen;
    if((buff[0] = 0xa5) && (buff[1] == 0x5a))
    {
        memcpy(&framelen,buff+2,sizeof(uint16_t));

        if(framelen < 6)
        {
            return 2;
        }
        else
        {
            if(len > (framelen-1))
            {
                if(buff[framelen - 1] == 0xaa)
                {
                    checksum = 0;
                    for(i = 2; i<framelen-2;i++)
                    {
                        checksum += buff[i];
                    }

                    checksum = checksum& 0xff;

                    if(buff[framelen - 2] == checksum)
                    {
                        parse(buff+4,framelen-8);
                    }
                    else
                    {

                    }
                }
                else
                {

                }
                return framelen;
            }
            else
            {
                return 0;
            }
        }
    }
    else
    {
        return 1;
    }
}

uint32_t MainWindow::Analyse_MCU(uint8_t *buff, uint32_t len)
{
    uint32_t reslen = 0;
    char num[20];
    uint8_t send_buff[20];

    /* IAP */
    if(vUpdateFlag == 2)
    {
        if(vUpdateState == 0)
        {
            if(strstr((char*)buff,"Read to receive the code file") != NULL)
            {
                vqLabel_FwUpdate_State_Data->setText(tr("正在更新"));
                vUpdateState = 1;
                FirmWareSend(0);
                vReadFileIndex++;
                vqProgressBar_FwUpdate_Prog->setValue(vReadFileIndex * 512 *100/vReadFileSize);

                vQtimer_UpdateMcu->start(50);
                reslen =  len;

            }

        }
        else if(vUpdateState == 1)
        {
            if(strstr((char*)buff,"Running the new user code") != NULL)
            {
                vqLabel_FwUpdate_State_Data->setText(tr("更新完成"));
                vqProgressBar_FwUpdate_Prog->setValue(100);
                vUpdateFlag = 0;

            }
        }
    }
    /* ISP */
    else if(vUpdateFlag == 3)
    {
        if(vUpdateState == 0)
        {
            if(strstr((char*)buff,"1560 is the size of new code") != NULL)
            {
                vqLabel_FwUpdate_State_Data->setText(tr("正在更新"));
                vUpdateState = 1;

                itoa(vReadFileSize,num,10);/* 把整数转换成字符串，并返回指向转换后的字符串的指针 */

                memcpy(send_buff,"iap",4);
                memcpy(send_buff+4,num,strlen(num));
                memcpy(send_buff+4+strlen(num),"\r\n",2);

                serial->write((char*)send_buff,strlen(num)+6);

                vQtimer_FwUpdate->stop();
                vQtimer_FwUpdate->start(5000);

                vQtimer_IspStart->stop();
                reslen =  len;

            }

        }
        else if(vUpdateState == 1)
        {
            if(strstr((char*)buff,"Read to receive the code file") != NULL)
            {
                vqLabel_FwUpdate_State_Data->setText(tr("正在更新"));
                vUpdateState = 2;
                FirmWareSend(0);
                vReadFileIndex++;
                vqProgressBar_FwUpdate_Prog->setValue(vReadFileIndex * 512 *100/vReadFileSize);
                vQtimer_FwUpdate->stop();
                vQtimer_UpdateMcu->start(50);
                reslen =  len;

            }
        }
        else if(vUpdateState == 2)
        {
            if(strstr((char*)buff,"Running the new user code") != NULL)
            {
                vqLabel_FwUpdate_State_Data->setText(tr("更新完成"));
                vqProgressBar_FwUpdate_Prog->setValue(100);
                vUpdateFlag = 0;
                vQtimer_FwUpdate->stop();
            }
        }
    }
}

void MainWindow::parse(uint8_t *buff, uint32_t len)
{
    if(vUpdateState == 0)
    {
        if(buff[0] == 0x04 && buff[1] == 0x10)  /* 收到返回指令 */
        {
            vqLabel_FwUpdate_State_Data->setText(tr("正在更新"));
            FirmWareSend(0);
            vReadFileIndex++;
            vUpdateState = 1;
            vQtimer_FwUpdate->stop();
            vQtimer_FwUpdate->start(5000);
        }
    }
    else if(vUpdateState == 1)
    {
        if(vReadFileIndex >= vReadFileNum)  /* 将所有的包发送完成 */
        {
            vqLabel_FwUpdate_State_Data->setText(tr("更新完成"));
            vqProgressBar_FwUpdate_Prog->setValue(100);
            vQtimer_FwUpdate->stop();
            vUpdateFlag = 0;

        }
        else
        {
            FirmWareSend(vReadFileIndex);
            vqProgressBar_FwUpdate_Prog->setValue(vReadFileIndex*512*100/vReadFileSize);
            vReadFileIndex++;
            vQtimer_FwUpdate->stop();
            vQtimer_FwUpdate->start(5000);

        }
    }

}

void MainWindow::ComsendDate(uint8_t cmd, uint8_t *buff, uint32_t len)
{
    char *pos;
    int sum;
    int i;
    char checksum;
    short int cnt;

    if(PushButton_Open->text() == "connect")
    {
        vqLabel_FwUpdate_State_Data->setText(tr("serial port is disconnected"));
        tim->start();
        return;
    }

    cnt = 8+ len;
    pos =  (char*)malloc(cnt);

    if(pos != NULL)
    {
        /* 包头 */
        pos[0] = (char)0xa5;
        pos[1] = 0x5a;
        memcpy(pos + 2,&cnt,sizeof(short int));     /* 长度 */
        pos[4] = 0x05;
        pos[5] = cmd;

        memcpy(pos+6,buff,len);
        sum = 0;
        for(i = 2; i < cnt-2;i++)
        {
            sum += pos[i];
        }
        checksum = sum;
        pos[cnt -2] = checksum;
        pos[cnt -1] = (char)0xaa;   /* 包尾 */

        serial->write(pos,cnt);     /* 将数据打包发送出去 */

        free(pos);

    }
    else
    {
        vqLabel_FwUpdate_State_Data->setText(tr("内存出错"));
    }


}

void MainWindow::Update_UI_Send(uint32_t index, uint8_t *buff, uint32_t len)
{
    uint8_t *sendbuff;

    sendbuff = (uint8_t*)malloc(len+4);
    if(sendbuff != NULL)
    {
        memcpy(sendbuff,&index,4);
        memcpy(sendbuff+4,buff,len);
        ComsendDate(0x11,sendbuff,len+4);
        free(sendbuff);
    }
}

void MainWindow::Updat_UI_Start(uint32_t filesize)
{
    uint8_t buff[5];

    vqLabel_FwUpdate_State_Data->setText(tr("准备更新"));

    buff[0] = 0x00;
    memcpy(buff+1,&filesize,4);
    ComsendDate(0x10,buff,5);
}

void MainWindow::Update_MCU_Iap_Start(uint32_t filesize)
{
   uint8_t buff[5];
   vHead = 0;
   vCount = 0;
   memset(vBuff, 0,2*1024);
   vqLabel_FwUpdate_State_Data->setText("准备更新");
   buff[0] = 0x01;


   memcpy(buff+1,&filesize,4);
   ComsendDate(0x10,buff,5);
}

void MainWindow::Update_MUC_Isp_start(uint32_t filesize)
{
    vQtimer_IspStart->start(50);
    vqLabel_FwUpdate_State_Data->setText(tr("MCU电路板连接串口后重新上电"));
}

void MainWindow::FirmWareSend(uint32_t index)
{
    QString filename = vqLineEdit_FwUpdate_Path->text();

    QFile file(filename);
    char buff[512];
    uint32_t reslen;

    if(file.open(QIODevice::ReadOnly))
    {
        if(file.seek(index*512))
        {

            reslen = file.read(buff,512);   // 数据累心不对也是保错no mat
            if(reslen >= 0)
            {
                Update_UI_Send(index,(uint8_t*)buff,reslen);
            }
        }
        file.close();
    }
    else
    {
        vqLabel_FwUpdate_State_Data->setText(tr("文件错误"));
    }
    vQtimer_FwUpdate->stop();
    vQtimer_FwUpdate->start(5000);
}

void MainWindow::FirmWareSendMcu(uint32_t index)
{
    QString filename = vqLineEdit_FwUpdate_Path->text();

    QFile file(filename);
    char buff[512];
    uint32_t reslen;

    if(file.open(QIODevice::ReadOnly))
    {
        if(file.seek(index*512))
        {

            reslen = file.read(buff,512);   // 数据累心不对也是保错no mat
            if(reslen >= 0)
            {
                serial->write((char*)buff,reslen);
            }
        }
        file.close();
    }
    else
    {
        vqLabel_FwUpdate_State_Data->setText(tr("文件错误"));
    }
}
//打开串口，关闭串口按钮
void MainWindow::SlotPushButton_Open()
{
    qDebug() << "open button is pass";
    if(ComBox_Port->currentText().isEmpty())
    {

        return;
    }
    if(PushButton_Open->text() == "connect")
    {
        serial->setPortName(ComBox_Port->currentText());
        if(serial->open(QIODevice::ReadWrite))
        {
            //设置波特率
            serial->setBaudRate(ComBox_Baud->currentText().toInt());
            //设置数据位
            switch(ComBox_DateBit->currentText().toInt())
            {
            case 5:
                serial->setDataBits(QSerialPort::Data5);
                break;

            case 6:
                serial->setDataBits(QSerialPort::Data6);
                break;

            case 7:
                serial->setDataBits(QSerialPort::Data7);
                break;

            case 8:
                serial->setDataBits(QSerialPort::Data8);
                break;

            default:
                break;
            }

            //设置校验位

            switch (ComBox_CheckBit->currentIndex()) {

            case 0:     //无校验
                serial->setParity(QSerialPort::NoParity);
                qDebug() << "index 0";
                break;
            case 1:     //奇校验
                serial->setParity(QSerialPort::OddParity);
                qDebug() << "index 1";
                break;
            case 2:     //偶校验
                serial->setParity(QSerialPort::EvenParity);
                qDebug() << "index 2";
                break;
            default:
                qDebug() << "warn:check bit seting wrong";
                break;
            }

            //设置停止位
            switch (ComBox_StopBit->currentIndex()) {
            case 0:     //1个停止位
                serial->setStopBits(QSerialPort::OneStop);
                break;
            case 1:     //1.5个停止位
                serial->setStopBits(QSerialPort::OneAndHalfStop);
                break;
            case 2:     //2个停止位
                serial->setStopBits(QSerialPort::TwoStop);
                break;
            }
            qDebug() <<"stopBit： "<< ComBox_StopBit->currentIndex();
            //设置流控
            serial->setFlowControl(QSerialPort::NoFlowControl);
            PushButton_Open->setText("disconnect");
            Label_StateDate->setText("serial port is connected");

            //建立串口接收槽函数

            connect(serial,&QSerialPort::readyRead,this,&MainWindow::revice_data,Qt::QueuedConnection);


        }
    }
    else
    {
        serial->close();        //关闭串口
        PushButton_Open->setText("connect");
        Label_StateDate->setText("serial port is disconnected");
    }
}

void MainWindow::SlotComboBox_FwUpdate_dev(int index)
{
    if(vqComboBox_FwUpdate_Dev->currentText() == "UI")
    {
        vqComboBox_FwUpdate_Type->setDisabled(true);
    }
    else if(vqComboBox_FwUpdate_Dev->currentText()== "MCU")
    {
        vqComboBox_FwUpdate_Type->setDisabled(false);
    }
}

void MainWindow::SlotOpenFile()
{
    QString dir;

    QFile file("path.txt");
    if(file.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        QTextStream in(&file);
        dir = in.readAll();
        qDebug() << dir;
    }
    /* 弹出对话框 */
    QString fileName = QFileDialog::getOpenFileName(this,"打开",dir,"files (*.bin)");
    if(fileName.length() > 0)
    {
        /* 将文件的目录地址保存在一个.txt文件中 */
        vqLineEdit_FwUpdate_Path->setText(fileName);
        QFile file("path.txt");
        file.open(QIODevice::WriteOnly|QIODevice::Truncate|QIODevice::Text);
        QTextStream out(&file);
        out << fileName;
        file.close();
    }
    vqLabel_FwUpdate_State_Data->setText(tr("准备更新"));
    vqProgressBar_FwUpdate_Prog->setValue(0);


}

void MainWindow::SlotFirmwareStat()
{
    /* 读地址文件目录地址 */
    QString fileName = vqLineEdit_FwUpdate_Path->text();
    QFileInfo info(fileName);
    QFile file(fileName);

    if(PushButton_Open->text() == "connect")
    {
        vqLabel_FwUpdate_State_Data->setText(tr("串口未打开"));
    }
    else
    {
        if(file.open(QIODevice::ReadOnly))
        {
            vqProgressBar_FwUpdate_Prog->setValue(0);
            vReadFileIndex = 0;
            vReadFileSize = file.size();
            vReadFileNum = vReadFileSize / 512; /* 获取包数 */

            if(vReadFileSize % 512)
            {
                vReadFileNum ++;    /* 尾数 */
            }
            qDebug() << "flie number:" << vReadFileNum;
            vQtimer_FwUpdate->stop();

            if(vqComboBox_FwUpdate_Dev->currentText() ==  "UI")
            {
                vUpdateFlag = 1;
                vUpdateState = 0;
                Updat_UI_Start(vReadFileSize);
            }
            else if(vqComboBox_FwUpdate_Dev->currentText() == "MCU")
            {
                if(vqComboBox_FwUpdate_Type->currentText() == "IAP")
                {
                    vUpdateFlag = 2;
                    vUpdateState = 0;
                    Update_MCU_Iap_Start(vReadFileSize);
                }
                else if(vqComboBox_FwUpdate_Type->currentText() == "ISP")
                {
                    vUpdateFlag = 3;
                    vUpdateState = 0;
                    Update_MUC_Isp_start(vReadFileSize);
                }
            }
            file.close();

        }
        else
        {
            vqLabel_FwUpdate_State_Data->setText(tr("文件未打开"));
        }
    }

}

void MainWindow::SoltFwUpdateTimerDone()
{
    vqLabel_FwUpdate_State_Data->setText(tr("更新失败"));
    vUpdateFlag = 0;

}

void MainWindow::SoltFwUpdateTimerIspStart()
{
    serial->write("iap\r\n",5);
}

void MainWindow::SloatTimerUpdateMcu()
{
    if(vReadFileIndex < vReadFileNum)
    {
        //        FirmWare_Update(vReadFileIndex);
        /* 设置进度条 */
        vqProgressBar_FwUpdate_Prog->setValue(vReadFileIndex * 512 * 100 /vReadFileNum);
        vReadFileIndex++;
    }
    else
    {
        vqProgressBar_FwUpdate_Prog->setValue(100);
        vQtimer_UpdateMcu->stop();
        vQtimer_FwUpdate->stop();
        vQtimer_FwUpdate->start(5000);

    }
}











